package com.smart.community.property.controller;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.result.Result;
import com.smart.community.property.dto.SanitationFeeEditDTO;
import com.smart.community.property.dto.SanitationFeeGenerateDTO;
import com.smart.community.property.entity.SanitationFee;
import com.smart.community.property.service.ISanitationFeeService;
import com.smart.community.property.vo.SanitationFeeVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;

/**
 * 卫生费管理控制器
 * @author Wu.Liang
 * @since 2024-12-21
 */
@Slf4j
@RestController
@RequestMapping("/property/sanitation-fees")
@Tag(name = "卫生费管理", description = "卫生费账单生成、查询、统计、催缴等接口")
public class SanitationFeeController {

    @Autowired
    private ISanitationFeeService sanitationFeeService;

    /**
     * 分页查询卫生费账单
     */
    @GetMapping
    @Operation(summary = "分页查询卫生费账单", description = "支持按社区、状态等条件查询，返回包含房户号、社区名、楼栋名、单元名的详细信息")
    public Result<PageResult<SanitationFeeVO>> getSanitationFeeList(
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "社区ID") @RequestParam(required = false) Long communityId,
            @Parameter(description = "缴费状态：0-未缴费，1-已缴费，2-逾期") @RequestParam(required = false) String paymentStatus,
            @Parameter(description = "计费周期") @RequestParam(required = false) String billingPeriod,
            @Parameter(description = "楼栋ID") @RequestParam(required = false) Long buildingId,
            @Parameter(description = "单元ID") @RequestParam(required = false) Long unitId,
            @Parameter(description = "房户ID") @RequestParam(required = false) Long householdId,
            @Parameter(description = "房户ID列表，多个用逗号分隔") @RequestParam(required = false) String householdIds) throws Exception {
    	
    	// 处理householdIds参数
    	List<Long> householdIdList = null;
    	if (householdIds != null && !householdIds.trim().isEmpty()) {
    		try {
    			householdIdList = new ArrayList<>();
    			String[] ids = householdIds.split(",");
    			for (String id : ids) {
    				if (id.trim().matches("\\d+")) {
    					householdIdList.add(Long.parseLong(id.trim()));
    				}
    			}
    			log.info("设置房户ID列表筛选条件: {}", householdIdList);
    		} catch (Exception e) {
    			log.warn("解析householdIds参数失败: {}, 忽略该参数", householdIds);
    		}
    	}
    	
    	PageResult<SanitationFeeVO> result = sanitationFeeService.getSanitationFeePage(current, size, communityId, paymentStatus, billingPeriod, buildingId, unitId, householdId, householdIdList);
        return Result.success("查询成功", result);
    }

    /**
     * 获取卫生费详情
     */
    @GetMapping("/{billId}")
    @Operation(summary = "获取卫生费详情", description = "获取指定卫生费账单的详细信息，包含房户号、社区名、楼栋名、单元名")
    public Result<SanitationFeeVO> getSanitationBillDetail(
            @Parameter(description = "账单ID") @PathVariable Long billId) throws Exception {
        log.info("获取卫生费详情，账单ID: {}", billId);
        SanitationFeeVO bill = sanitationFeeService.getSanitationFeeDetail(billId);
        if (bill != null) {
            return Result.success("查询成功", bill);
        } else {
            return Result.fail("账单不存在");
        }
    }

    /**
     * 查询用户未缴费卫生费账单
     */
    @GetMapping("/user/{userId}/unpaid")
    @Operation(summary = "查询用户未缴费卫生费账单", description = "获取指定用户的所有未缴费卫生费账单")
    public Result<List<SanitationFee>> getUnpaidSanitationBillsByUserId(
            @Parameter(description = "用户ID") @PathVariable Long userId) throws Exception {
        log.info("查询用户未缴费卫生费账单，用户ID: {}", userId);
        List<SanitationFee> bills = sanitationFeeService.getUnpaidSanitationFeesByUserId(userId);
        return Result.success("查询成功", bills);
    }

    /**
     * 生成卫生费账单（支持计费月份时间段）
     */
    @PostMapping("/generate")
    @Operation(summary = "生成卫生费", description = "生成卫生费用")
    @ApiLog(
        logTitle = "生成卫生费",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.ADD
    )
    public Result<Map<String, Integer>> generateSanitationFee(
            @Parameter(description = "生成参数") @RequestBody @Valid SanitationFeeGenerateDTO generateDTO) throws Exception {
        log.info("生成卫生费账单（时间段），参数: {}", generateDTO);
        int count = sanitationFeeService.generateSanitationFeeByRange(
                generateDTO.getCommunityId(),
                generateDTO.getBillingMonthRange(),
                generateDTO.getDueDate(),
                generateDTO.getRemark()
        );
        
        // 返回前端期望的数据结构：{count: number}
        Map<String, Integer> result = new HashMap<>();
        result.put("count", count);
        return Result.success("生成成功", result);
    }

    /**
     * 批量生成卫生费账单
     */
    @PostMapping("/batch-generate")
    @Operation(summary = "批量生成卫生费账单", description = "支持多个社区同时生成账单")
    public Result<Map<String, Integer>> batchGenerateSanitationFee(
            @Parameter(description = "社区ID列表") @RequestParam List<Long> communityIds,
            @Parameter(description = "计费月份") @RequestParam @DateTimeFormat(pattern = "yyyy-MM") LocalDate billingMonth,
            @Parameter(description = "人均费用") @RequestParam BigDecimal perPersonFee) throws Exception {
        log.info("批量生成卫生费账单，社区IDs: {}, 计费月份: {}, 人均费用: {}", communityIds, billingMonth, perPersonFee);
        Map<String, Integer> result = sanitationFeeService.batchGenerateSanitationFee(communityIds, billingMonth, perPersonFee);
        return Result.success("批量生成成功", result);
    }

    /**
     * 编辑卫生费信息（只允许编辑费用金额、缴费状态，到期日期不允许修改）
     */
    @PutMapping("/{billId}")
    @Operation(summary = "更新卫生费", description = "更新卫生费信息")
    @ApiLog(
        logTitle = "更新卫生费",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.UPDATE
    )
    public Result<Boolean> updateSanitationBill(
            @Parameter(description = "账单ID") @PathVariable Long billId,
            @Parameter(description = "编辑数据") @RequestBody @Valid SanitationFeeEditDTO dto) throws Exception {
        log.info("编辑卫生费信息，账单ID: {}, 编辑数据: {}", billId, dto);
        boolean success = sanitationFeeService.updateSanitationFee(billId, dto);
        if (success) {
            return Result.success("编辑成功", true);
        } else {
            return Result.fail("编辑失败");
        }
    }

    /**
     * 卫生费缴费
     */
    @PostMapping("/{billId}/pay")
    @Operation(summary = "卫生费缴费", description = "卫生费缴费")
    @ApiLog(
        logTitle = "卫生费缴费",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.UPDATE
    )
    public Result<Boolean> paySanitationFee(
            @Parameter(description = "账单ID") @PathVariable Long billId,
            @Parameter(description = "支付金额") @RequestParam BigDecimal paymentAmount,
            @Parameter(description = "支付方式") @RequestParam String paymentMethod) throws Exception {
        log.info("卫生费缴费，账单ID: {}, 金额: {}, 支付方式: {}", billId, paymentAmount, paymentMethod);
        boolean success = sanitationFeeService.paySanitationFee(billId, paymentAmount, paymentMethod);
        if (success) {
            return Result.success("缴费成功", true);
        } else {
            return Result.fail("缴费失败");
        }
    }

    /**
     * 发送卫生费催缴提醒
     */
    @PostMapping("/{billId}/remind")
    @Operation(summary = "发送卫生费催缴提醒", description = "向用户发送卫生费催缴提醒通知")
    public Result<Boolean> sendSanitationReminder(
            @Parameter(description = "账单ID") @PathVariable Long billId,
            @Parameter(description = "提醒方式：sms-短信，email-邮件，app-APP推送") @RequestParam String remindType) throws Exception {
        log.info("发送卫生费催缴提醒，账单ID: {}, 提醒方式: {}", billId, remindType);
        boolean success = sanitationFeeService.sendSanitationReminder(billId, remindType);
        if (success) {
            return Result.success("提醒发送成功", true);
        } else {
            return Result.fail("提醒发送失败");
        }
    }

    /**
     * 批量发送卫生费催缴提醒
     */
    @PostMapping("/batch-remind")
    @Operation(summary = "批量发送卫生费催缴提醒", description = "批量向逾期用户发送卫生费催缴提醒")
    public Result<Map<String, Integer>> batchSendSanitationReminder(
            @Parameter(description = "社区ID") @RequestParam Long communityId,
            @Parameter(description = "提醒方式：sms-短信，email-邮件，app-APP推送") @RequestParam String remindType) throws Exception {
        log.info("批量发送卫生费催缴提醒，社区ID: {}, 提醒方式: {}", communityId, remindType);
        Map<String, Integer> result = sanitationFeeService.batchSendSanitationReminder(communityId, remindType);
        return Result.success("批量提醒发送成功", result);
    }

    /**
     * 获取卫生费统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取卫生费统计信息", description = "获取指定社区的卫生费收缴统计")
    public Result<Map<String, Object>> getSanitationFeeStatistics(
            @Parameter(description = "社区ID") @RequestParam Long communityId,
            @Parameter(description = "年份") @RequestParam(defaultValue = "#{T(java.time.LocalDate).now().getYear()}") Integer year) throws Exception {
        log.info("获取卫生费统计信息，社区ID: {}, 年份: {}", communityId, year);
        Map<String, Object> statistics = sanitationFeeService.getSanitationFeeStatistics(communityId, year);
        return Result.success("查询成功", statistics);
    }

    /**
     * 删除卫生费记录
     */
    @DeleteMapping("/{billId}")
    @Operation(summary = "删除卫生费", description = "删除卫生费记录")
    @ApiLog(
        logTitle = "删除卫生费",
        logType = 2,
        moduleName = "物业管理",
        operationType = ApiLogOperationType.DELETE
    )
    public Result<Boolean> deleteSanitationBill(
            @Parameter(description = "账单ID") @PathVariable Long billId) throws Exception {
        log.info("删除卫生费记录，账单ID: {}", billId);
        boolean success = sanitationFeeService.removeById(billId);
        if (success) {
            return Result.success("删除成功", true);
        } else {
            return Result.fail("删除失败");
        }
    }

    // ==================== 房户详情Tab页接口 ====================

    /**
     * 获取房户卫生费列表
     * 
     * @param householdId 房户ID
     * @param current 当前页
     * @param size 每页大小
     * @return 卫生费列表
     * @throws Exception 统一异常
     */
    @GetMapping("/household/{householdId}")
    @Operation(summary = "获取房户卫生费列表", description = "根据房户ID获取关联的卫生费列表")
    public Result<PageResult<SanitationFeeVO>> getHouseholdSanitationFees(
            @Parameter(description = "房户ID") @PathVariable Long householdId,
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) throws Exception {
        log.info("获取房户卫生费列表，房户ID：{}，当前页：{}，每页大小：{}", householdId, current, size);
        
        PageResult<SanitationFeeVO> result = sanitationFeeService.getHouseholdSanitationFees(householdId, current, size);
        
        log.info("获取房户卫生费列表成功，房户ID：{}，卫生费数量：{}", householdId, result.getTotal());
        return Result.success(result);
    }
}
